using GameFramework.Localization;
using GameFramework.Resource;
using LS.Event;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityGameFramework.Runtime;
using LS.Localization;

namespace LS
{
    public class LocalizationLoaderComponent : CustomGameFrameworkComponent
    {
        public Language defaultLanguage = Language.ChineseSimplified;
        public bool reloadDataWhenSetup = true;
        public bool saveLanguageTypeWhenSetup = true;
        public bool loadLanguageTypeWhenInit = true;

        private LocalizationSetting m_LocalizationSetting = null;
        private LocalizationComponent m_Localization = null;
        private ResourceComponent m_Resources = null;
        private EventComponent m_Event = null;
        private SettingComponent m_Setting = null;

        public bool Available => m_LocalizationSetting != null;
        public Language Language => m_Localization.Language;
        public Language SystemLanguage => m_Localization.SystemLanguage;
        public LocalizationSetting.Content[] LanguageDatas => m_LocalizationSetting?.Collection?.ToArray()?? new LocalizationSetting.Content[0];

        private bool m_LocalizationInitFinish = false;
        private bool m_LanguageTypeSetup = false;
        private bool m_LanguageDataLoaded = false;

        private void Start()
        {
            m_Localization = GameEntry.GetComponent<LocalizationComponent>();
            m_Resources = GameEntry.GetComponent<ResourceComponent>();
            m_Event = GameEntry.GetComponent<EventComponent>();
            m_Setting = GameEntry.GetComponent<SettingComponent>();
        }

        public void Init(string filePath,object userData)
        {
            Log.Debug($"LocalizationLoaderComponent.Init {filePath}");
            m_Resources.LoadAsset(
                assetName:filePath,
                userData: userData,
                assetType: typeof(LocalizationSetting),
                loadAssetCallbacks:new LoadAssetCallbacks(
                    loadAssetSuccessCallback: OnLoadLocalizationSettingSuccess,
                    loadAssetFailureCallback: OnLoadLocalizationSettingFail));
        }

        public void Init(LocalizationSetting setting)
        {
            m_LocalizationInitFinish = false;
            m_LanguageTypeSetup = false;
            m_LanguageDataLoaded = false;

            this.m_LocalizationSetting = setting;
            m_LocalizationInitFinish = true;
            if (loadLanguageTypeWhenInit)
            {
                if (!LoadLanguageFromSetting())
                {
                    ResetLanguageToSystemOrDefault();
                }
            }

        }

        public void ResetLanguageToSystemOrDefault()
        {
            var systemLanguage = SystemLanguage;

            if (HasLanguageData(systemLanguage))
            {
                SetupLanguage(systemLanguage);
            }
            else
            {
                SetupLanguage(defaultLanguage);
            }
        }

        public bool SetupLanguage(Language language)
        {
            if (m_LanguageTypeSetup && Language == language)
                return true;

            if (!m_LocalizationSetting.HasLanguage(language))
                return false;

            m_Localization.Language = language;
            m_LanguageTypeSetup = true;

            if (reloadDataWhenSetup)
                LoadLanguageDatas(language);

            if (saveLanguageTypeWhenSetup)
                SaveLanguageToSetting();

            return true;
        }

        public bool HasLanguageData(Language language)
        {
            return m_LocalizationSetting.HasLanguage(language);
        }

        public bool LoadLanguageDatas(Language language)
        {
            Log.Debug($"Load Language: {language.ToString()}");
            var setting = m_LocalizationSetting.GetLanguage(language);
            if (setting == null) return false;
            
            for (int i = 0; i < setting.Datas.Count; i++)
            {
                TextAsset data = setting.Datas[i];
                Log.Debug($"Load Language Data: {data.text}");
                m_Localization.ParseData(data.text);
            }
            m_LanguageDataLoaded = true;
            return true;
        }

        public bool LoadLanguageFromSetting()
        {
            if (m_Setting.HasSetting("Language"))
            {
                int l = m_Setting.GetInt("Language");
                Language language = (Language)l;
                SetupLanguage(language);
                return true;
            }
            return false;
        }

        public void SaveLanguageToSetting()
        {
            m_Setting.SetInt("Language", (int)Language);
            m_Setting.Save();
        }

        private void OnLoadLocalizationSettingSuccess(string assetName, object asset, float duration, object userData)
        {
            Log.Info("Localization Setting Load Success");
            Init(asset as LocalizationSetting);

            var eventArgs = LSGameEventArgs.Create<LoadLocalizationSettingSuccessEventArgs>();
            eventArgs.assetName = assetName;
            eventArgs.duration = duration;
            eventArgs.userData = userData;
            m_Event.Fire(this, eventArgs);
        }

        private void OnLoadLocalizationSettingFail(string assetName, LoadResourceStatus status, string errorMessage, object userData)
        {
            Log.Error($"Load LocalizationSetting Fail, assetName: {assetName}, Status:{status.ToString()}, error: {errorMessage}");
            var eventArgs = LSGameEventArgs.Create<LoadLocalizationSettingFailEventArgs>();
            eventArgs.assetName = assetName;
            eventArgs.status = status;
            eventArgs.errorMessage = errorMessage;
            eventArgs.userData = userData;
            m_Event.Fire(this, eventArgs);
        }
    }
}
